package Engine;

//
//  Character.java
//  Engine
//
//  Created by Jeremy W on 6/8/10.
//  Copyright 2010 Jeremy Walker. All rights reserved.
//
import java.net.URL;
import java.net.URLConnection;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class CharacterDetail {
	private String achPoints;
	private String classId;
	private String genderId;
	private String level;
	private String name;
	private String raceId;
	private String url;
	private String realm;
	private String guild;
	// added 08/19/10
	private String battlegroup;
	private String classname;
	private String faction;
	private String gender;
	private Date lastlogin;
	private String race;

	public CharacterDetail() {
	}

	public CharacterDetail(Element el) {
		this.setAchPoints(el.getAttribute("achPoints"));
		this.setClassId(el.getAttribute("classId"));
		this.setGenderId(el.getAttribute("genderId"));
		this.setLevel(el.getAttribute("level"));
		this.setName(el.getAttribute("name"));
		this.setRaceId(el.getAttribute("raceId"));
		this.setUrl(el.getAttribute("url"));
	}

	public void saveCharacter(Connection conn) throws Exception {
		// Connection conn = new JdbcConnection().getConnection();
		
		PreparedStatement pst = conn
				.prepareStatement("insert into wow_data "+
".player_list (guild, level,battlegroup,classname,faction,gender,last_login,race,url,name,realm, updatetime ) values ( ?,?, ?,?,?,?,?,?,?,?,?, current_timestampa ) ");
		int i = 1;
		pst.setString(i++, this.getGuild());
		pst.setString(i++, this.getLevel());
		pst.setString(i++, this.getBattlegroup());
		pst.setString(i++, this.getClassname());
		pst.setString(i++, this.getFaction());
		pst.setString(i++, this.getGender());
		pst.setTimestamp(i++, new java.sql.Timestamp(this.getLastlogin().getTime()));
		pst.setString(i++, this.getRace());
		pst.setString(i++, this.getUrl());
		pst.setString(i++, this.getName());
		pst.setString(i++, this.getRealm());
		pst.executeUpdate();
		System.out.println("Saved: " + this.getName());
		pst.close(); pst = null;

	}
	public void saveCharacterFromGuild(Connection conn) throws Exception {
		// Connection conn = new JdbcConnection().getConnection();
		
		PreparedStatement pst = conn
				.prepareStatement("insert into wow_data "+
".player_list (guild, level,ach_pts,url,name,realm, updatetime ) values ( ?,?,?,?,?,?, current_timestampa ) ");
		int i = 1;
		pst.setString(i++, this.getGuild());
		pst.setString(i++, this.getLevel());
		pst.setString(i++, this.getAchPoints());
		pst.setString(i++, this.getUrl());
		pst.setString(i++, this.getName());
		pst.setString(i++, this.getRealm());
		pst.executeUpdate();
		System.out.println("Saved: " + this.getName());
		pst.close(); pst = null;

	}
	public void updateCharacterFromGuild(Connection conn) throws Exception {
		// Connection conn = new JdbcConnection().getConnection();
		PreparedStatement pst = conn
				.prepareStatement("update wow_data.player_list set guild = ?,ach_pts = ?, level = ?, url = ?" +
						" updatetime = current_timestamp  where name = ? and realm = ?  ");
		int i = 1;
		pst.setString(i++, this.getGuild());
		pst.setString(i++, this.getAchPoints());
		pst.setString(i++, this.getLevel());
		pst.setString(i++, this.getUrl());
		pst.setString(i++, this.getName());
		pst.setString(i++, this.getRealm());

		pst.executeUpdate();
		pst.close(); pst = null;
	}
	public void updateCharacterFromToon(Connection conn) throws Exception {
		// Connection conn = new JdbcConnection().getConnection();
		PreparedStatement pst = conn
				.prepareStatement("update wow_data.player_list set" +
						" guild = ?,ach_pts = ?, level = ?, url = ?," +
						"battlegroup = ?, classname = ?, faction = ?, gender = ?, last_login = ?, race = ? " +
						" updatetime = current_timestamp  where name = ? and realm = ?  ");
		int i = 1;
		pst.setString(i++, this.getGuild());
		pst.setString(i++, this.getLevel());
		pst.setString(i++, this.getBattlegroup());
		pst.setString(i++, this.getClassname());
		pst.setString(i++, this.getFaction());
		pst.setString(i++, this.getGender());
		pst.setTimestamp(i++, new java.sql.Timestamp(this.getLastlogin().getTime()));
		pst.setString(i++, this.getRace());
		pst.setString(i++, this.getUrl());
		pst.setString(i++, this.getName());
		pst.setString(i++, this.getRealm());

		pst.executeUpdate();
		pst.close(); pst = null;
	}
	public String getGuild() {
		return guild;
	}

	public void setGuild(String guild) {
		this.guild = guild;
	}

	public String getRealm() {
		return realm;
	}

	public void setRealm(String realm) {
		this.realm = realm;
	}

	public String getAchPoints() {
		return achPoints;
	}

	public void setAchPoints(String achPoints) {
		this.achPoints = achPoints;
	}

	/** TODO set up map for toon classes **/
	public String getClassId() {
		return classId;
	}

	public void setClassId(String classId) {
		this.classId = classId;
	}

	/** TODO set up map for toon genders **/
	public String getGenderId() {
		return genderId;
	}

	public void setGenderId(String genderId) {
		this.genderId = genderId;
	}

	public String getLevel() {
		return level;
	}

	public void setLevel(String level) {
		this.level = level;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	/** TODO set up map for toon races **/
	public String getRaceId() {
		return raceId;
	}

	public void setRaceId(String raceId) {
		this.raceId = raceId;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public ArrayList getCharacters(Connection conn) throws Exception {
		ArrayList list = new ArrayList();
		ResultSet rs = conn
				.prepareStatement(
						"Select distinct name from wow_data.player_list where updatetime < (current_timestamp - interval 1 day) and realm in ('Mal\\'Ganis', 'Blood Furnace') limit 1000")
				.executeQuery();
		while (rs.next()) {
			list.add(rs.getString(1));
		}
		return list;
	}

	public void refreshCharacters(Connection conn) {
		try {
			
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
			CharacterDetail toon = new CharacterDetail();
			ArrayList toons = toon.getCharacters(conn);

			URL armory;
			URLConnection uconn;

			Document doc = null;
			NodeList guild;
			Node fstNode;
			Element el;
System.out.println("Size: " + toons.size());
			for (int i = 0; i < toons.size(); i++) {
				System.out.println("Running Toon: " + toons.get(i));
					Thread.sleep(750);
					System.gc();
					armory = new URL(
							"http://www.wowarmory.com/search.xml?searchQuery="
									+ toons.get(i) + "&searchType=characters");

					uconn = armory.openConnection();
					uconn.setRequestProperty("User-Agent",
							"Mozilla/4.0 (compatible; MSIE 6.0; ");
					try {
						doc = DocumentBuilderFactory.newInstance()
								.newDocumentBuilder()
								.parse(new InputSource(uconn.getInputStream()));
					} catch (Exception e) {
						if (e.getMessage().contains("500 for URL:"))
							continue;
					}
					/*
					 * if(doc == null) continue;
					 */
					doc.getDocumentElement().normalize();

					guild = doc.getElementsByTagName("character");
					for (int k = 0; k < guild.getLength(); k++) {
						fstNode = guild.item(k);
						el = (Element) fstNode;
						toon.setName(el.getAttribute("name"));
						toon.setRealm(el.getAttribute("realm")); //System.out.println("Realm: " + el.getAttribute("realm"));
						toon.setGuild(el.getAttribute("guild"));
						toon.setBattlegroup(el.getAttribute("battleGroup"));
						toon.setClassname(el.getAttribute("class"));
						toon.setFaction(el.getAttribute("faction"));
						toon.setGender(el.getAttribute("gender"));
						toon.setLastlogin(sdf.parse(el.getAttribute("lastLoginDate")));
						toon.setUrl(el.getAttribute("url"));
						toon.setLevel(el.getAttribute("level"));
						
						try {
							toon.saveCharacter(conn);

						} catch (SQLException e) {

							if (e.getMessage().contains("Duplicate entry")) {
								toon.updateCharacterFromToon(conn);
								continue;
							}
							e.printStackTrace(); //throw (e);
						}
					}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public String toString() {
		return "-- Name: " + this.name + "\n" + "---- Ach. Points: "
				+ this.achPoints + "\n" + "---- Class Id: " + this.classId
				+ "\n" + "---- Gender Id: " + this.genderId + "\n"
				+ "---- Level: " + this.level + "\n" + "---- Race Id: "
				+ this.raceId + "\n" + "---- URL: " + this.url + "\n";
	}

	public String getBattlegroup() {
		return battlegroup;
	}

	public void setBattlegroup(String battlegroup) {
		this.battlegroup = battlegroup;
	}

	public String getClassname() {
		return classname;
	}

	public void setClassname(String classname) {
		this.classname = classname;
	}

	public String getFaction() {
		return faction;
	}

	public void setFaction(String faction) {
		this.faction = faction;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public Date getLastlogin() {
		return lastlogin;
	}

	public void setLastlogin(Date lastlogin) {
		this.lastlogin = lastlogin;
	}

	public String getRace() {
		return race;
	}

	public void setRace(String race) {
		this.race = race;
	}

}
